package com.yunxin.admin.system.application.impl;

import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yunxin.admin.system.application.RoleQueryService;
import com.yunxin.admin.system.application.assembler.BasePageAssembler;
import com.yunxin.admin.system.application.assembler.RoleAssembler;
import com.yunxin.admin.system.application.command.RolePageCommand;
import com.yunxin.admin.system.application.dto.OptionDTO;
import com.yunxin.admin.system.application.dto.RoleInfoDTO;
import com.yunxin.admin.system.application.dto.RolePageDTO;
import com.yunxin.admin.system.application.dto.base.BasePageDTO;
import com.yunxin.admin.system.domain.model.role.RoleMenuRepository;
import com.yunxin.admin.system.infra.common.constant.SystemConstants;
import com.yunxin.admin.system.infra.framework.security.util.SecurityUtils;
import com.yunxin.admin.system.infra.persistence.entity.SysRoleDO;
import com.yunxin.admin.system.infra.persistence.entity.SysUserRoleDO;
import com.yunxin.admin.system.infra.persistence.mapper.SysRoleMapper;
import com.yunxin.admin.system.infra.persistence.mapper.SysUserRoleMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author zero°
 * @since 2023-07-11
 */
@Service
@RequiredArgsConstructor
public class RoleQueryServiceImpl implements RoleQueryService {

    private final SysRoleMapper sysRoleMapper;

    private final RoleMenuRepository roleMenuRepository;

    private final BasePageAssembler basePageAssembler;

    private final RoleAssembler roleAssembler;

    private final SysUserRoleMapper sysUserRoleMapper;
    @Override
    public Page<RolePageDTO> getRolePage(RolePageCommand command) {
        BasePageDTO basePageDTO = basePageAssembler.formBasePageCommand(command);
        final String keywords = command.getKeywords();
        // 查询数据
        Page<SysRoleDO> page =  sysRoleMapper.selectPage(new Page<>(basePageDTO.getPageNum(), basePageDTO.getPageSize()),
                new LambdaQueryWrapper<SysRoleDO>()
                        .and(CharSequenceUtil.isNotBlank(command.getKeywords()),
                                wrapper -> wrapper.like(CharSequenceUtil.isNotBlank(keywords), SysRoleDO::getName, keywords)
                                                .or()
                                                .like(CharSequenceUtil.isNotBlank(keywords), SysRoleDO::getCode, keywords)
                        )
                        // 非超级管理员不显示超级管理员角色
                        .ne(!SecurityUtils.X.isRoot(), SysRoleDO::getCode, SystemConstants.ROOT_ROLE_CODE)
                        .ne(!SecurityUtils.X.isRoot(), SysRoleDO::getCode, SystemConstants.BOKE_MERCHANT_ADMIN)
                        .eq(SysRoleDO::getBoke,1)
        );
        return roleAssembler.toRolePageDTO(page);
    }

    @Override
    public SysRoleDO getRoleByCode(String code) {
        return sysRoleMapper.selectOne(new LambdaQueryWrapper<SysRoleDO>().eq(SysRoleDO::getCode, code));
    }

    @Override
    public List<OptionDTO<Long>> listRole() {
        // 查询数据
        List<SysRoleDO> roles =  sysRoleMapper.selectList(new LambdaQueryWrapper<SysRoleDO>()
                .ne(!SecurityUtils.X.isRoot(), SysRoleDO::getCode, SystemConstants.ROOT_ROLE_CODE)
                .ne(SysRoleDO::getId, SystemConstants.DEFAULT_MERCHANT_USER_ROLE_ID)
                .ne(SysRoleDO::getCode, SystemConstants.BOKE_MERCHANT_ADMIN)
                .eq(SysRoleDO::getBoke,1)
                .select(SysRoleDO::getId, SysRoleDO::getName)
                .orderByAsc(SysRoleDO::getSort)
        );
        return roleAssembler.toOptionDTOList(roles);
    }

    @Override
    public RoleInfoDTO getRoleById(Long roleId) {
        SysRoleDO sysRoleDO = sysRoleMapper.selectById(roleId);
        return roleAssembler.toRoleInfoDTO(sysRoleDO);
    }

    @Override
    public List<SysUserRoleDO> getRoleListByUserId(Long userId) {
        return sysUserRoleMapper.selectList(new QueryWrapper<SysUserRoleDO>().eq("user_id", userId));
    }

    @Override
    public List<Long> getRoleMenuIds(Long roleId) {
        return roleMenuRepository.listMenuIdsByRoleId(roleId);
    }
}
